# -*- coding: utf-8 -*-

import luhn

from common.mch import db as mch_db
from common.risk import db as risk_db
from common.third import qiji, miidow, tonglue_withdraw, hydra_withdraw, group_withdraw, \
    shuangqian_withdraw, meifubao_withdraw, onepay_withdraw, kyjhpay_withdraw, xinglongpay_withdraw, flashpay_withdraw
from common.utils import track_logging
from common.withdraw import db as withdraw_db
from common.withdraw.model import WITHDRAW_ORDER_STATUS, CHANNEL_TYPE
from common.utils.exceptions import ParamError

_LOGGER = track_logging.getLogger(__name__)

CHANNEL_HANDLER = {
    CHANNEL_TYPE.QIJI: qiji,
    CHANNEL_TYPE.MIIDOW: miidow,
    CHANNEL_TYPE.TONGLUE_WITHDRAW: tonglue_withdraw,
    CHANNEL_TYPE.HYDRA_WITHDRAW: hydra_withdraw,
    CHANNEL_TYPE.GROUP_WITHDRAW: group_withdraw,
    CHANNEL_TYPE.SHUANGGIAN_WITHDRAW: shuangqian_withdraw,
    CHANNEL_TYPE.MEIFUBAO_WITHDRAW: meifubao_withdraw,
    CHANNEL_TYPE.ONEPAY_WITHDRAW: onepay_withdraw,
    CHANNEL_TYPE.KYJHPAY_WITHDRAW: kyjhpay_withdraw,
    CHANNEL_TYPE.XINGLONGPAY_WITHDRAW: xinglongpay_withdraw,
    CHANNEL_TYPE.FLASHPAY_WITHDRAW: flashpay_withdraw,
}

BIG_BANK = [
    '中国银行',
    '建设银行',
    '农业银行',
    '工商银行',
    '中国工商银行',
    '中国建设银行',
    '中国农业银行',
    '交通银行',
    '中国邮政储蓄银行',
    '邮政银行',
    '中国邮政银行',
    '中国光大银行',
    '光大银行',
    '中国民生银行',
    '民生银行',
    '招商银行',
    '中信银行',
    '华夏银行',
    '浦发银行',
    '平安银行',
    '广发银行',
    '兴业银行'
]

ERROR_TYPE = {
    'bank_card_error': '银行卡卡号错误',
    'bank_error': '银行类型错误',
    'bank_subbranch_erro': '支行信息错误',
}


def _bankcard_valid(order):
    ''' 卡号luhn校验 '''
    try:
        if order.pay_account_num:
            if risk_db.get_risky_card_by_num(order.pay_account_num, order.mch_id):
                return False
            return luhn.verify(order.pay_account_num)
        else:
            return False
    except:
        _LOGGER.info('order %s pay_account_num')
        return False


def _bank_valid(order):
    ''' 银行名称校验 '''
    if order.pay_account_bank[0].isdigit():
        return False
    return True


def _bank_subbranch_valid(order):
    ''' 支行信息校验 '''
    if not order.pay_account_bank_subbranch:
        if order.pay_account_bank not in BIG_BANK:
            return False
    if order.pay_account_bank_subbranch[0].isdigit():
        return False
    return True


def _withdraw_info_check(order):
    ''' 提现信息整体校验 '''
    if not _bankcard_valid(order):
        return False, ERROR_TYPE['bank_card_error']
    if not _bank_valid(order):
        return False, ERROR_TYPE['bank_error']
    # if not _bank_subbranch_valid(order):
    #     return False, ERROR_TYPE['bank_subbranch_erro']
    return True, 'Success'


def check_order(order):
    ''' 检查提现信息并更新数据 '''
    check_passed, detail = _withdraw_info_check(order)
    if check_passed:
        return True
    else:
        order.status = WITHDRAW_ORDER_STATUS.REJECTED
        order.detail = detail
        order.save()
        return False


def process_withdraw(order):
    """ 判断并提交三方处理 """
    mch_info = mch_db.get_mch_info(order.mch_id)
    if float(order.amount) < mch_info['third_min_amount'] or float(order.amount) > mch_info['third_max_amount']:
        _LOGGER.warn('process_withdraw amount error : %s, %s', order.id, order.amount)
        return None
    channel = withdraw_db.get_channel(order)
    if not channel:
        _LOGGER.warn('none third channel availiable for: %s' % order.as_dict())
        return None
    channel_type = channel.channel_type
    channel_handler = CHANNEL_HANDLER[channel_type]
    third_status = channel_handler.create_order(order, channel)
    return third_status


def resend_withdraw(order):
    """ 重新提交三方处理 """
    if order.status == WITHDRAW_ORDER_STATUS.WAIT:
        channel = withdraw_db.get_channel(order)
        if not channel:
            _LOGGER.warn('none third channel availiable for: %s' % order.id)
            raise ParamError(u'没有可用下分通道 订单号: %s' % order.id)
    else:
        channel = withdraw_db.get_channel_by_withdraw_order(order)
    channel_type = channel.channel_type
    channel_handler = CHANNEL_HANDLER[channel_type]
    third_status = channel_handler.create_order(order, channel)
    return third_status

def query_withdraw(order):
    channel = withdraw_db.get_channel_by_withdraw_order(order)
    channel_type = channel.channel_type
    channel_handler = CHANNEL_HANDLER[channel_type]
    status = channel_handler.query_order(order, channel)
    return status